package com.ybb.production.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.ybb.production.domain.GarmentProductionBianfei;
import com.ybb.production.domain.GarmentProductionCuttingBedInfo;
import com.ybb.production.domain.GarmentProductionOrder;
import com.ybb.production.domain.GarmentProductionProcess;
import com.ybb.production.dto.GarmentProductionCompleteDetailDTO;
import com.ybb.production.dto.GarmentProductionOrderDetailDTO;
import com.ybb.production.dto.GarmentProductionOrderQueryDTO;
import com.ybb.production.dto.GarmentProductionOrderUpsertDTO;
import com.ybb.production.mapper.GarmentProductionBianfeiMapper;
import com.ybb.production.mapper.GarmentProductionCuttingBedInfoMapper;
import com.ybb.production.mapper.GarmentProductionOrderMapper;
import com.ybb.production.mapper.GarmentProductionProcessMapper;
import com.ybb.production.responce.*;
import com.ybb.production.service.IGarmentProductionOrderService;
import com.yubb.common.core.redis.RedisCache;
import com.yubb.common.utils.DateUtils;
import com.yubb.common.utils.StringUtils;
import com.yubb.system.service.impl.SysUserServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 生产工单Service业务层处理
 *
 * @author ruoyi
 * @date 2023-09-06
 */
@Service
public class GarmentProductionOrderServiceImpl implements IGarmentProductionOrderService {
    @Autowired
    private GarmentProductionOrderMapper garmentProductionOrderMapper;

    @Autowired
    private GarmentProductionProcessMapper garmentProductionProcessMapper;

    @Autowired
    private GarmentProductionBianfeiMapper garmentProductionBianfeiMapper;

    @Autowired
    private GarmentProductionCuttingBedInfoMapper garmentProductionCuttingBedInfoMapper;

    @Autowired
    private SysUserServiceImpl sysUserService;

    @Autowired
    private RedisCache redisCache;

    private static final String COUNTER_KEY = "work_order_counter";

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");


    /**
     * 查询生产工单
     *
     * @param id 生产工单主键
     * @return 生产工单
     */
    @Override
    public GarmentProductionOrder selectGarmentProductionOrderById(Long id) {
        return garmentProductionOrderMapper.selectGarmentProductionOrderById(id);
    }

    /**
     * 查询生产工单列表
     *
     * @param orderQueryDTO 生产工单
     * @return 生产工单
     */
    @Override
    public List<GarmentProductionOrderPageResp> selectGarmentProductionOrderList(GarmentProductionOrderQueryDTO orderQueryDTO) {
        // return response
        List<GarmentProductionOrderPageResp> respList;
        // 1. 查询生产工单列表
        List<GarmentProductionOrder> orders = garmentProductionOrderMapper.selectGarmentProductionOrderList(orderQueryDTO);
        if (CollectionUtils.isEmpty(orders)) {
            return new ArrayList<>();
        }
        // 2. 转换为response
        respList = orders.stream().map(order -> {
            GarmentProductionOrderPageResp resp = new GarmentProductionOrderPageResp();
            BeanUtils.copyProperties(order, resp);
            List list = JSONObject.parseObject(order.getDynamicData(), List.class);
            long totalQuantity = 0L;
            if (!CollectionUtils.isEmpty(list)) {
                for (Object o : list) {
                    JSONObject jsonObject = JSONObject.parseObject(o.toString());
                    // todo ：这个字段需要和前端对下
                    totalQuantity = totalQuantity + Long.parseLong(jsonObject.get("total").toString());
                }
            }
            resp.setTotalQuantity(String.valueOf(totalQuantity));

            return resp;
        }).collect(Collectors.toList());
        List<Long> orderIds = orders.stream().map(GarmentProductionOrder::getId).collect(Collectors.toList());
        // 查询工序数量
        List<Map<String, Object>> processList = garmentProductionProcessMapper.selectCountByOrderIds(orderIds);
        Map<String, Object> processMap = processList.stream().collect(Collectors.toMap(map -> map.get("orderId").toString(), map -> map.get("count")));
        // 查询编菲数量
        List<Map<String, Object>> bianfeiList = garmentProductionBianfeiMapper.selectQuantityByOrderIds(orderIds);
        Map<String, Object> bianfeiMap = bianfeiList.stream().collect(Collectors.toMap(map -> map.get("orderId").toString(), map -> map.get("quantity")));
        for (GarmentProductionOrderPageResp re : respList) {
            if (processMap.get(re.getId().toString()) != null) {
                re.setProcessCount(processMap.get(re.getId().toString()).toString());

            }
            if (bianfeiMap.get(re.getId().toString()) != null) {
                re.setCutQuantity(bianfeiMap.get(re.getId().toString()).toString());
            }
        }
        return respList;
    }

    /**
     * 新增生产工单
     *
     * @param garmentProductionOrder 生产工单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public GarmentProductionOrder insertGarmentProductionOrder(GarmentProductionOrderUpsertDTO garmentProductionOrder) {
        // 0. 生成工单号
        setOrderNo(garmentProductionOrder);
        garmentProductionOrder.setDelFlag("0");
        GarmentProductionOrder garmentProductionOrder1 = new GarmentProductionOrder();
        BeanUtils.copyProperties(garmentProductionOrder, garmentProductionOrder1);
        // 1. 新增生产工单
        garmentProductionOrder1.setStatus("0");
        this.garmentProductionOrderMapper.insertGarmentProductionOrder(garmentProductionOrder1);

        // 2. 新增生产工序
        if (StringUtils.isNotEmpty(garmentProductionOrder.getProcessList())) {
            garmentProductionOrder.getProcessList().forEach(process -> {
                GarmentProductionProcess garmentProductionProcess = new GarmentProductionProcess();
                BeanUtils.copyProperties(garmentProductionOrder, garmentProductionProcess);
                BeanUtils.copyProperties(process, garmentProductionProcess);
                garmentProductionProcess.setOrderId(garmentProductionOrder1.getId());
                garmentProductionProcessMapper.insertGarmentProductionProcess(garmentProductionProcess);
            });
        }
        return garmentProductionOrder1;
    }

    private void setOrderNo(GarmentProductionOrderUpsertDTO garmentProductionOrder) {
        // 查询工单号是否存在
        if (StringUtils.isEmpty(garmentProductionOrder.getOrderNo())) {
            String orderNumber = generateWorkOrderNumber();
            // 判断自动生产的工单号是否存在
            while (garmentProductionOrderMapper.selectCountByOrderNo(orderNumber) > 0) {
                orderNumber = generateWorkOrderNumber();
            }
            garmentProductionOrder.setOrderNo(orderNumber);
        } else {
            int count = garmentProductionOrderMapper.selectCountByOrderNo(garmentProductionOrder.getOrderNo());
            if (count > 0) {
                throw new RuntimeException("工单号已存在");
            }
        }
    }

    /**
     * 修改生产工单
     *
     * @param orderDTO 生产工单
     * @return 结果
     */
    @Override
    public int updateGarmentProductionOrder(GarmentProductionOrderUpsertDTO orderDTO) {
        orderDTO.setDelFlag("0");
        GarmentProductionOrder garmentProductionOrder1 = new GarmentProductionOrder();
        BeanUtils.copyProperties(orderDTO, garmentProductionOrder1);

        // 3. 修改生产工序
        if (StringUtils.isNotEmpty(orderDTO.getProcessList())) {
            garmentProductionProcessMapper.deleteGarmentProductionProcessByOrderIds(new Long[]{orderDTO.getId()});
            orderDTO.getProcessList().forEach(process -> {
                GarmentProductionProcess garmentProductionProcess = new GarmentProductionProcess();
                BeanUtils.copyProperties(orderDTO, garmentProductionProcess);
                BeanUtils.copyProperties(process, garmentProductionProcess);
                garmentProductionProcess.setOrderId(orderDTO.getId());
                garmentProductionProcess.setId(null);
                garmentProductionProcessMapper.insertGarmentProductionProcess(garmentProductionProcess);
            });
        }
        return garmentProductionOrderMapper.updateGarmentProductionOrder(garmentProductionOrder1);
    }

    /**
     * 批量删除生产工单
     *
     * @param ids 需要删除的生产工单主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteGarmentProductionOrderByIds(Long[] ids) {
        garmentProductionProcessMapper.deleteGarmentProductionProcessByOrderIds(ids);
        garmentProductionCuttingBedInfoMapper.deleteCuttingBedByOrderIds(ids);
        garmentProductionBianfeiMapper.deleteBianfeiByOrderIds(ids);
        return garmentProductionOrderMapper.deleteGarmentProductionOrderByIds(ids);
    }

    /**
     * 删除生产工单信息
     *
     * @param id 生产工单主键
     * @return 结果
     */
    @Override
    public int deleteGarmentProductionOrderById(Long id) {
        return garmentProductionOrderMapper.deleteGarmentProductionOrderById(id);
    }

    @Override
    public GarmentProductionOrderDetailDTO selectProductionOrderDetail(Long id) {
        GarmentProductionOrderDetailDTO detailDTO = new GarmentProductionOrderDetailDTO();
        // 1. 查询生产工单
        GarmentProductionOrder order = garmentProductionOrderMapper.selectGarmentProductionOrderById(id);
        if (order == null) {
            return null;
        }
        BeanUtils.copyProperties(order, detailDTO);
        // 查询工序数
        ArrayList<Long> orderIdsList = new ArrayList<>();
        orderIdsList.add(id);
        int processCnt = garmentProductionProcessMapper.qeryProcessCnt(orderIdsList);
        List list = JSONObject.parseObject(order.getDynamicData(), List.class);
        long totalQuantity = 0L;
        if (!CollectionUtils.isEmpty(list)) {
            for (Object o : list) {
                JSONObject jsonObject = JSONObject.parseObject(o.toString());
                // todo ：这个字段需要和前端对下
                totalQuantity = totalQuantity + Long.parseLong(jsonObject.get("total").toString());
            }
        }
        detailDTO.setQuantity(String.valueOf(totalQuantity));
        // 查询编菲数量
        List<Map<String, Object>> bianfeiList = garmentProductionBianfeiMapper.selectQuantityByOrderIds(Collections.singletonList(id));
        Map<String, Object> bianfeiMap = bianfeiList.stream().collect(Collectors.toMap(map -> map.get("orderId").toString(), map -> map.get("quantity")));
        if (bianfeiMap.get(id.toString()) != null) {
            long value = Objects.isNull(bianfeiMap.get(id.toString())) ? 0L : Long.parseLong(bianfeiMap.get(id.toString()).toString());
            detailDTO.setCutQuantity(String.valueOf(value / processCnt));
        }
        // todo: 补充用户其他字段
//        sysUserService.selectUsersByIds(Collections.singletonList(Long.valueOf(order.getCreateBy()))).forEach(user -> {
//            detailDTO.setCreateBy(user.getUserId().toString());
//            detailDTO.setCreateByName(user.getNickName());
//        });
        return detailDTO;
    }

    @Override
    public List<Map<String, Object>> detailList(Long id) {
        GarmentProductionOrder order = garmentProductionOrderMapper.selectGarmentProductionOrderById(id);
        // 1. 下单数据
        List<Map<String, Object>> list2 = JSON.parseObject(order.getDynamicData(), new TypeReference<List<Map<String, Object>>>() {
        });

        ArrayList<Long> ids = new ArrayList<>();
        ids.add(id);
        int processCnt = garmentProductionProcessMapper.qeryProcessCnt(ids);

        // 2. 扎号数据
        List<Map<String, Object>> bedNoData = garmentProductionBianfeiMapper.selectBianfieGroup(id,processCnt);
        Set<Object> color = new HashSet<>();
        for (Map<String, Object> bedNoDatum : bedNoData) {
            color.add(bedNoDatum.get("color"));
        }
        List<Map<String, Object>> list1 = new ArrayList<>();
        for (Object o : color) {
            Map<String, Object> map1 = new HashMap<>();
            for (Map<String, Object> bedNoDatum : bedNoData) {
                if (bedNoDatum.get("color").equals(o)) {
                    map1.put("color", o);
                    map1.put(bedNoDatum.get("size").toString(), Integer.parseInt(bedNoDatum.get("quantity").toString()));
                }
            }
            list1.add(map1);
        }
        // 合并颜色集合
        List<Map<String, Object>> mergedColors = mergeColors(list2, list1);
        if (!CollectionUtils.isEmpty(mergedColors)){
            creteOneTotal(mergedColors);
            // 输出合并后的颜色集合
            JSONObject resultJson = createResultJson(mergedColors);
            resultJson.put("color", "合计");
            mergedColors.add(resultJson);
        }
        return mergedColors;
    }

    @Override
    public GarmentProductionOrderStaResp getProductionOrderStatistics() {
        GarmentProductionOrderStaResp resp = new GarmentProductionOrderStaResp();
        resp.setCompleteQuantity("0");
        resp.setCompletePrice("0");
        resp.setProducingPrice("0");
        resp.setProducingQuantity("0");
        // 1. 查询生产工单id集合按状态分组
        List<Map<String, String>> orderStatus = garmentProductionOrderMapper.qryIdsGroupStatus();
        List<String> allIds = new ArrayList<>();
        String producingPriceIds = "";
        String completePriceIds = "";
        for (Map<String, String> status : orderStatus) {
            if ("0".equals(status.get("status"))) {
                producingPriceIds = status.get("ids");
            } else if ("1".equals(status.get("status"))) {
                completePriceIds = status.get("ids");
            }
        }
        if (StringUtils.isNotEmpty(producingPriceIds)) {
            List<String> producingPriceIdsList = Arrays.asList(producingPriceIds.split(","));
            String producingPriceSum = garmentProductionProcessMapper.qrySumPriceByOrderIds(producingPriceIdsList);
            BigDecimal bigDecimal = new BigDecimal(producingPriceSum);
            producingPriceSum = bigDecimal.setScale(2, RoundingMode.HALF_UP).toString();
            resp.setProducingPrice(producingPriceSum);
            String producingTotal = garmentProductionCuttingBedInfoMapper.qrySumCuttingBedByOrderIds(producingPriceIdsList);
            resp.setProducingQuantity(producingTotal);
            allIds.addAll(producingPriceIdsList);
        }
        if (StringUtils.isNotEmpty(completePriceIds)) {
            List<String> completePriceIdsList = Arrays.asList(producingPriceIds.split(","));
            String completePriceSum = garmentProductionProcessMapper.qrySumPriceByOrderIds(completePriceIdsList);
            // 四舍五入保留两位小数
            BigDecimal bigDecimal = new BigDecimal(completePriceSum);
            completePriceSum = bigDecimal.setScale(2, RoundingMode.HALF_UP).toString();
            resp.setCompletePrice(completePriceSum);
            // 已完成件数
            String completeTotal = garmentProductionCuttingBedInfoMapper.qrySumCuttingBedByOrderIds(completePriceIdsList);
            resp.setCompleteQuantity(completeTotal);
            allIds.addAll(completePriceIdsList);
        }

        // 2. 计算总数据 用 BigDecimal 计算 并且保留两位小数
        resp.setTotalPrice(new BigDecimal(resp.getCompletePrice()).add(new BigDecimal(resp.getProducingPrice())).toString());
        resp.setTotalQuantity(Integer.parseInt(resp.getCompleteQuantity()) + Integer.parseInt(resp.getProducingQuantity()) + "");
        resp.setTotalOrder(allIds.size() + "");
        resp.setModelQuantity(allIds.size() + "");

        if (allIds.isEmpty()) {
            return resp;
        }
        // 3. 查询总件数
        Integer totalCnt = 0;
        List<GarmentProductionOrder> dyamicDataList = garmentProductionOrderMapper.selectDyamicDataByIds(allIds);
        for (GarmentProductionOrder order : dyamicDataList) {
            JSONArray dyamic = JSONArray.parseArray(order.getDynamicData());
            for (Object o : dyamic) {
                JSONObject jsonObject = JSONObject.parseObject(o.toString());
                String total = jsonObject.get("total").toString();
                totalCnt += Integer.parseInt(total);
            }
        }
        resp.setTotalPiece(totalCnt + "");

        // 4. 查询总裁床数
        int bianfeiQuilty = garmentProductionBianfeiMapper.qrySumBianfeiQuilty(allIds);
        resp.setTotalCuttingBed(String.valueOf(bianfeiQuilty));
        return resp;
    }

    @Override
    public List<GarmentProductionProgressByBedNoResp> progressByBedNo(Long orderId) {
        List<GarmentProductionProgressByBedNoResp> respList = new ArrayList<>();
        // 1. 查询裁床信息
        List<GarmentProductionCuttingBedInfo> bedInfos = garmentProductionCuttingBedInfoMapper.selectBedInfoByOrderId(orderId);

        if (CollectionUtils.isEmpty(bedInfos)) {
            return new ArrayList<>();
        }

        List<Long> cutBedIds = bedInfos.stream().map(GarmentProductionCuttingBedInfo::getId).collect(Collectors.toList());

        List<GarmentBianfeiSumResp> bianfeiStaList = garmentProductionBianfeiMapper.qryTotalAndCompleteByCuttingBedIds(cutBedIds, null);
        Map<Long, GarmentBianfeiSumResp> bianfeiStaMap = bianfeiStaList.stream().collect(Collectors.toMap(GarmentBianfeiSumResp::getCuttindbedId, bianfeiSumResp -> bianfeiSumResp));

        // 查询最后一道工序的id
        List<Map<String, Object>> lastProcessList = garmentProductionProcessMapper.selectGarmentProductionProcessLastProcess(Collections.singleton(orderId));
        Long lastProcess = lastProcessList.stream().map(map -> Long.parseLong(map.get("id").toString())).collect(Collectors.toList()).get(0);
        List<GarmentBianfeiSumResp> lastProcessSumList = garmentProductionBianfeiMapper.qryTotalAndCompleteByCuttingBedIds(cutBedIds, lastProcess);
        Map<Long, GarmentBianfeiSumResp> lastProcessSumMap = lastProcessSumList.stream().collect(Collectors.toMap(GarmentBianfeiSumResp::getCuttindbedId, bianfeiSumResp -> bianfeiSumResp));

        // 查询工序数量
        GarmentProductionProcess process = new GarmentProductionProcess();
        process.setOrderId(orderId);
        List<GarmentProductionProcess> processList = garmentProductionProcessMapper.selectGarmentProductionProcessList(process);
        // 查询按工序纬度统计结果
        List<GarmentBianfeiSumResp> bianfeiByProcess = garmentProductionBianfeiMapper.qryGroupByProcess(cutBedIds);
        Map<Long, List<GarmentBianfeiSumResp>> bianfeiByProcessMap = bianfeiByProcess.stream().collect(Collectors.groupingBy(GarmentBianfeiSumResp::getProcessId));

        // 最后组装数据
        int processCnt = processList.size();
        for (GarmentProductionCuttingBedInfo bedInfo : bedInfos) {
            GarmentProductionProgressByBedNoResp resp = new GarmentProductionProgressByBedNoResp();
            resp.setBedNo(bedInfo.getbedNo());
            resp.setCuttingBedQuantity(Integer.parseInt(bianfeiStaMap.get(bedInfo.getId()).getTotalQuantity()) / processCnt + "");
            resp.setCompletePieceQuantity(Objects.isNull(lastProcessSumMap.get(bedInfo.getId())) ? "0" : lastProcessSumMap.get(bedInfo.getId()).getCompleteQuantity());
            resp.setTotalQuantity(bianfeiStaMap.get(bedInfo.getId()).getTotalQuantity());
            resp.setAccomplishQuantity(Objects.isNull(bianfeiStaMap.get(bedInfo.getId())) ? "0": bianfeiStaMap.get(bedInfo.getId()).getCompleteQuantity());
            resp.setCreateTime(DateUtils.parseDateToStr("yyyy-MM-dd", bedInfo.getCreateTime()));
            resp.setCuttingBedId(bedInfo.getId());
            // 查询完成详情
            List<GarmentProductionProgressByBedNoResp.CuttingBedProcess> cuttingBedProcessList = new ArrayList<>();
            for (GarmentProductionProcess productionProcess : processList) {
                GarmentBianfeiSumResp garmentBianfeiSumResp = bianfeiByProcessMap.get(productionProcess.getId()).get(0);
                GarmentProductionProgressByBedNoResp.CuttingBedProcess cuttingBedProcess = new GarmentProductionProgressByBedNoResp.CuttingBedProcess();
                cuttingBedProcess.setCuttingBedId(bedInfo.getId());
                cuttingBedProcess.setProcessName(productionProcess.getProcessName());
                cuttingBedProcess.setPrice(productionProcess.getPrice());
                cuttingBedProcess.setTotalQuantity(Long.valueOf(garmentBianfeiSumResp.getTotalQuantity()));
                cuttingBedProcess.setCompleteQuantity(Long.valueOf(garmentBianfeiSumResp.getCompleteQuantity()));
                cuttingBedProcess.setRemainderQuantity(cuttingBedProcess.getTotalQuantity() - cuttingBedProcess.getCompleteQuantity());
                cuttingBedProcess.setProcessId(productionProcess.getId());
                cuttingBedProcessList.add(cuttingBedProcess);
                resp.setCuttingBedProcessList(cuttingBedProcessList);
            }
            respList.add(resp);
        }
        return respList;
    }

    @Override
    public List<GarmentProductionOrderDetailResp> getProductionOrderDetailList(Long orderId) {
        // 查询裁床信息
        List<GarmentProductionCuttingBedInfo> bedInfos = garmentProductionCuttingBedInfoMapper.selectBedInfoByOrderId(orderId);

        List<GarmentProductionOrderDetailResp> respList = new ArrayList<>();
        // 查询编菲总数量和完成数据
        List<Long> bedIds = bedInfos.stream().map(GarmentProductionCuttingBedInfo::getId).collect(Collectors.toList());
        List<GarmentBianfeiSumResp> bianfeiList = garmentProductionBianfeiMapper.qryTotalAndCompleteByCuttingBedIds(bedIds, null);
        Map<Long, GarmentBianfeiSumResp> bianfeiMap = bianfeiList.stream().collect(Collectors.toMap(GarmentBianfeiSumResp::getCuttindbedId, bianfeiSumResp -> bianfeiSumResp));

        // 查询工序数量根据工单id
        int processCnt = garmentProductionProcessMapper.qeryProcessCnt(new ArrayList<Long>() {{
            add(orderId);
        }});
        for (GarmentProductionCuttingBedInfo bedInfo : bedInfos) {
            GarmentProductionOrderDetailResp resp = new GarmentProductionOrderDetailResp();
            resp.setBedNo(bedInfo.getbedNo());
            resp.setCreateTime(DateUtils.parseDateToStr("yyyy-MM-dd", bedInfo.getCreateTime()));
            int cutNum = bianfeiMap.get(bedInfo.getId()) == null ? 0 : Integer.parseInt(bianfeiMap.get(bedInfo.getId()).getTotalQuantity());
            resp.setCutNum(cutNum / processCnt);
            int completeNum = bianfeiMap.get(bedInfo.getId()) == null ? 0 : Integer.parseInt(bianfeiMap.get(bedInfo.getId()).getCompleteQuantity());
            resp.setCompleteNum(completeNum / processCnt);
            resp.setProcessNum(cutNum);
            resp.setProcessCompleteNum(completeNum);
            resp.setProcessCompleteRate(new BigDecimal(completeNum).divide(new BigDecimal(cutNum), 2, RoundingMode.HALF_UP).toString());
            respList.add(resp);
        }
        return respList;
    }

    @Override
    public int updateOrderStatus(GarmentProductionOrderUpsertDTO garmentProductionOrder) {
        return garmentProductionOrderMapper.updateOrderStatus(garmentProductionOrder);
    }

    @Override
    public List<GarmentBianfeiCompleteDetailResp> completeDetail(GarmentProductionCompleteDetailDTO dto) {
        List<GarmentBianfeiCompleteDetailResp> respList = new ArrayList<>();
        GarmentProductionBianfei bianfeiDto = new GarmentProductionBianfei();
        bianfeiDto.setCuttindbedId(dto.getCuttingId());
        bianfeiDto.setProcessId(dto.getProcessId());
        List<GarmentProductionBianfei> garmentProductionBianfeis = garmentProductionBianfeiMapper.selectGarmentProductionBianfeiList(bianfeiDto);
        for (GarmentProductionBianfei bianfei : garmentProductionBianfeis) {
            GarmentBianfeiCompleteDetailResp resp = new GarmentBianfeiCompleteDetailResp();
            resp.setCuttingBedId(bianfei.getCuttindbedId());
            resp.setColor(bianfei.getColor());
            resp.setSize(bianfei.getSize());
            resp.setCuttingBedQuantity(Math.toIntExact(bianfei.getQuantity()));
            resp.setCompleteQuantity(Math.toIntExact(Objects.isNull(bianfei.getUpNumber()) ? 0 : bianfei.getUpNumber()));
            resp.setRemainderQuantity(Math.toIntExact(bianfei.getQuantity() - resp.getCompleteQuantity()));
            resp.setBundleNo(String.valueOf(bianfei.getBundleNo()));
            resp.setBoltNo(String.valueOf(bianfei.getBoltNo()));
            resp.setBianfeiId(bianfei.getId());
            respList.add(resp);
        }
        return respList;
    }

    @Override
    public List<GarmentProductionProgressByBedNoResp.CuttingBedProcess> combinedStatistics(Long orderId) {
        List<GarmentProductionProgressByBedNoResp.CuttingBedProcess> respList = new ArrayList<>();
        // 1. 查询所有工序
        List<GarmentProductionProcess> processList = garmentProductionProcessMapper.selectGarmentProductionProcessList(new GarmentProductionProcess() {{
            setOrderId(orderId);
        }});

        // 2. 查询所有编菲统计
        List<GarmentBianfeiSumResp> bianfeiList = garmentProductionBianfeiMapper.qryBianFeiProcessByOrderId(orderId);

        // 2.1 构建编菲统计map
        Map<Long, List<GarmentBianfeiSumResp>> bianfeiMap = bianfeiList.stream().collect(Collectors.groupingBy(GarmentBianfeiSumResp::getProcessId));

        // 3. 合并结果
        processList.forEach(process -> {
            GarmentProductionProgressByBedNoResp.CuttingBedProcess resp = new GarmentProductionProgressByBedNoResp.CuttingBedProcess();
            resp.setProcessId(process.getId());
            resp.setProcessName(process.getProcessName());
            resp.setPrice(process.getPrice());
            List<GarmentBianfeiSumResp> bianfeiSumResps = bianfeiMap.get(process.getId());
            if (CollectionUtils.isEmpty(bianfeiSumResps)) {
                resp.setTotalQuantity(0L);
                resp.setCompleteQuantity(0L);
                resp.setRemainderQuantity(0L);
            } else {
                resp.setTotalQuantity(Long.valueOf(bianfeiSumResps.get(0).getTotalQuantity()));
                resp.setCompleteQuantity(Long.valueOf(bianfeiSumResps.get(0).getCompleteQuantity()));
                resp.setRemainderQuantity(resp.getTotalQuantity() - resp.getCompleteQuantity());
            }
            respList.add(resp);
        });
        return respList;
    }

    private void creteOneTotal(List<Map<String, Object>> mergedColors) {
        // 将value里有斜杠的数据进行合并，合并规则是将斜杠前的数据相加，斜杠后的数据相加，组成新的map，新的map的key是total
        for (Map<String, Object> mergedColor : mergedColors) {
            int first = 0;
            int second = 0;
            for (String key : mergedColor.keySet()) {
                if (!key.equals("color") & !key.equals("total")) {
                    String[] values = mergedColor.get(key).toString().split("/");
                    if (values.length == 2) {
                        first += Integer.parseInt(values[0]);
                        second += Integer.parseInt(values[1]);
                    }
                }
            }
            mergedColor.put("total", first + "/" + second);
        }
    }

    public void updateGarmentProductionOrderbedNo(Long orderId, String bedNo) {
        Map map = new HashMap();
        map.put("orderId", orderId);
        map.put("bedNo", bedNo);
        garmentProductionOrderMapper.updateGarmentProductionOrderbedNo(map);
    }

    public static void main(String[] args) {
        // 两个颜色的集合示例
        List<Map<String, Object>> colors1 = new ArrayList<>();
        Map<String, Object> color1 = new HashMap<>();
        color1.put("color", "red");
        color1.put("S", 1);
        color1.put("M", 2);
        color1.put("L", 3);
        colors1.add(color1);
        Map<String, Object> color11 = new HashMap<>();
        color11.put("color", "white");
        color11.put("S", 11);
        color11.put("M", 21);
        color11.put("L", 31);
        colors1.add(color11);

        List<Map<String, Object>> colors2 = new ArrayList<>();
        Map<String, Object> color2 = new HashMap<>();
        color2.put("color", "red");
        color2.put("M", 4);
        color2.put("L", 5);
        color2.put("XL", 6);
        colors2.add(color2);
        Map<String, Object> color22 = new HashMap<>();
        color22.put("color", "white");
        color22.put("M", 41);
        color22.put("L", 51);
        color22.put("XL", 61);
        colors2.add(color22);

        // 合并颜色集合
        List<Map<String, Object>> mergedColors = mergeColors(colors1, colors2);
        // 输出合并后的颜色集合
        JSONObject resultJson = createResultJson(mergedColors);
        resultJson.put("color", "合计");
        mergedColors.add(resultJson);
        System.out.println(JSON.toJSONString(mergedColors));
    }

    public static JSONObject createResultJson(List<Map<String, Object>> colors) {
        JSONObject resultJson = new JSONObject();

        for (String key : colors.get(0).keySet()) {
            if (!key.equals("color")) {
                int total1 = 0;
                int total2 = 0;

                for (Map<String, Object> color : colors) {
                    String[] values = color.get(key).toString().split("/");
                    if (values.length == 2) {
                        total1 += Integer.parseInt(values[0]);
                        total2 += Integer.parseInt(values[1]);
                    }
                }

                String total = total1 + "/" + total2;
                resultJson.put(key, total);
            }
        }

        return resultJson;
    }

    public static List<Map<String, Object>> mergeColors(List<Map<String, Object>> colors1, List<Map<String, Object>> colors2) {
        List<Map<String, Object>> mergedColors = new ArrayList<>();

        for (Map<String, Object> color1 : colors1) {
            String color = (String) color1.get("color");

            // 在colors2中查找相同颜色的项
            Map<String, Object> color2 = findColor(colors2, color);

            // 如果colors2中没有相同颜色的项，将color1直接添加到合并集合中
            if (color2 == null) {
                color1.forEach((key, value) -> {
                    if (!key.equals("color")) {
                        color1.put(key, value + "/0");
                    }
                });
                mergedColors.add(color1);
            } else {
                // 合并color字段
                Map<String, Object> mergedColor = new HashMap<>();
                mergedColor.put("color", color);

                JSONArray sizes = new JSONArray();
                for (String key : color1.keySet()) {
                    if (!key.equals("color")) {
                        sizes.add(key);
                    }
                }
                for (String key : color2.keySet()) {
                    if (!key.equals("color")) {
                        if (!sizes.contains(key)) {
                            sizes.add(key);
                        }
                    }
                }

                // 合并尺码字段
                for (Object size : sizes) {
                    String sizeStr = (String) size;
                    int value1 = Integer.parseInt(color1.getOrDefault(sizeStr, 0).toString());
                    int value2 = Integer.parseInt(color2.getOrDefault(sizeStr, 0).toString());

                    // 如果color1没有该尺码字段，设置为0
                    if (!color1.containsKey(sizeStr)) {
                        mergedColor.put(sizeStr, "0/" + value2);
                    }
                    // 如果color2没有该尺码字段，设置为0
                    else if (!color2.containsKey(sizeStr)) {
                        mergedColor.put(sizeStr, value1 + "/0");
                    }
                    // 否则用斜杠连接两个值
                    else {
                        mergedColor.put(sizeStr, value1 + "/" + value2);
                    }
                }

                mergedColors.add(mergedColor);
            }
        }

        // 添加colors2中剩余的颜色
        for (Map<String, Object> color2 : colors2) {
            String color = (String) color2.get("color");
            if (findColor(mergedColors, color) == null) {
                color2.forEach((key, value) -> {
                    if (!key.equals("color")) {
                        color2.put(key, "0/" + value);
                    }
                });
                mergedColors.add(color2);
            }
        }

        return mergedColors;
    }

    private static Map<String, Object> findColor(List<Map<String, Object>> colors, String colorToFind) {
        for (Map<String, Object> color : colors) {
            String colorName = (String) color.get("color");
            if (colorName.equals(colorToFind)) {
                return color;
            }
        }
        return null;
    }

    public String generateWorkOrderNumber() {
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        String datePrefix = currentDate.format(DATE_FORMATTER);

        RedisTemplate redisTemplate = redisCache.redisTemplate;
        ValueOperations<String, Integer> valueOperations = redisTemplate.opsForValue();

        // 获取计数器的值并递增
        Integer counter = Math.toIntExact(valueOperations.increment(COUNTER_KEY, 1));

        // 获取计数器键的过期时间
        Long expirationTime = redisTemplate.getExpire(COUNTER_KEY);

        // 如果过期时间小于等于0，表示需要重置计数器
        if (expirationTime <= 0) {
            // 重置计数器
            valueOperations.set(COUNTER_KEY, 1); // 将计数器设置为1
            // 设置计数器键的过期时间为当天剩余的秒数
            LocalDateTime endOfDay = getEndOfDay(currentDate);
            redisTemplate.expireAt(COUNTER_KEY, Date.from(Instant.ofEpochSecond(endOfDay.toEpochSecond(ZoneOffset.UTC))));
            counter = 1; // 重置计数器后，将计数器设置为1
        }

        // 格式化计数器，确保至少有三位数字
        String counterFormatted = String.format("%03d", counter);

        // 生成工单号
        String workOrderNumber = datePrefix + counterFormatted;

        return workOrderNumber;
    }


    private LocalDateTime getEndOfDay(LocalDate date) {
        return date.atTime(23, 59, 59);
    }

}
